using System;

namespace SBPweb.Data
{

	/// <summary>
	/// Provides LogManager for Forge.Data via OnWrite event
	/// </summary>
	public class LogManager
	{

		#region Constructor logic

		/// <summary>
		/// Prevents user to direct instantiation
		/// </summary>
		private LogManager()
		{
		}

		#endregion

		#region Public static methods
		
		/// <summary>
		/// Fired when a log event written
		/// </summary>
		public static event LogWriteEventHandler OnWrite;

		/// <summary>
		/// Write critical to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void WriteCritical(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.Critical, obj, category);
		}

		/// <summary>
		/// Write error to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void WriteError(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.Error, obj, category);
		}

		/// <summary>
		/// Write info to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void WriteInfo(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.Information, obj, category);
		}

		/// <summary>
		/// Write something to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void Write(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.None, obj, category);
		}

		/// <summary>
		/// Write verbose to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void WriteVerbose(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.Verbose, obj, category);
		}

		/// <summary>
		/// Write warning to log
		/// </summary>
		/// <param name="sender">sender</param>
		/// <param name="obj">object</param>
		/// <param name="category">category</param>
		public static void WriteWarning(object sender, object obj, string category)
		{
			InvokeOnWrite(sender, SeverityLevel.Warning, obj, category);
		}

		private static void InvokeOnWrite(object sender, SeverityLevel severity, object obj, string category)
		{
			if (OnWrite != null)
			{
				OnWrite.Invoke(sender, new LogWriteEventArgs(severity, obj, category));
			}
		}

		#endregion

		#region Subclass definitions

		/// <summary>
		/// Event handler for log write
		/// </summary>
		/// <param name="sender">sender of event</param>
		/// <param name="e">LogWriteEventArgs</param>
		public delegate void LogWriteEventHandler(object sender, LogWriteEventArgs e);

		/// <summary>
		/// Enum for severity levels
		/// </summary>
		[Flags]
		public enum SeverityLevel
		{
			/// <summary>
			/// Auxilliary flag
			/// </summary>
			None = 0,
			/// <summary>
			/// Fatal error or application crash.
			/// </summary>
			Critical = 1,
			/// <summary>
			/// Recoverable error.
			/// </summary>
			Error = 2,
			/// <summary>
			/// Noncritical problem.
			/// </summary>
			Warning = 4,
			/// <summary>
			/// Informational message.
			/// </summary>
			Information = 8,
			/// <summary>
			/// Debugging trace.
			/// </summary>
			Verbose = 16
		}

		/// <summary>
		/// EventArgs for OnWrite event
		/// </summary>
		public class LogWriteEventArgs : EventArgs
		{

			private object mObject;
			private string mCategory;
			private SeverityLevel mSeverity;
			private int mPriority;

			/// <summary>
			/// Initializes a new LogWriteEventArgs instance
			/// </summary>
			/// <param name="severity">severity of event</param>
			/// <param name="obj">message of event</param>
			/// <param name="category">category of event</param>
			public LogWriteEventArgs(SeverityLevel severity, object obj, string category)
				: this(severity, obj, category, 0)
			{
			}

			/// <summary>
			/// Initializes a new LogWriteEventArgs instance
			/// </summary>
			/// <param name="severity">severity of event</param>
			/// <param name="obj">message of event</param>
			/// <param name="category">category of event</param>
			/// <param name="priority">priority of event</param>
			public LogWriteEventArgs(SeverityLevel severity, object obj, string category, int priority)
			{
				mSeverity = severity;
				mObject = obj;
				mCategory = category;
				mPriority = 0;
			}

			/// <summary>
			/// Returns the SeverityLevel of the event
			/// </summary>
			public SeverityLevel Severity
			{
				get
				{
					return mSeverity;
				}
			}

			/// <summary>
			/// Returns the message of the event
			/// </summary>
			public object Object
			{
				get
				{
					return mObject;
				}
			}

			/// <summary>
			/// Returns the category of the event
			/// </summary>
			public string Category
			{
				get
				{
					return mCategory;
				}
			}

			/// <summary>
			/// Returns the priority of the event
			/// </summary>
			public int Priority
			{
				get
				{
					return mPriority;
				}
			}
		}

		#endregion

	}
}